<template>
  <slot />
</template>

<script setup lang="ts" name="ActionCheckItem">
import type { PlatformRelation } from "../../../typings";
import { useSceneStore } from "../../../../../store/scene";
import { storeToRefs } from "pinia";
import {
  queryProductList,
  getRelationUsers,
  queryNoticeList,
  queryDingTalkUsers,
  queryWechatUsers,
  dingTalkDept,
  weChatDept,
  queryTemplateList,
  getTemplateDetail,
  getTags,
  detail as getDeviceDetail,
  queryNoPagingPost
} from "../../../../../api/others";
import { Form } from "ant-design-vue";
import {
  EventEmitter,
  EventSubscribeKeys,
  getParams,
} from "../../util";
import { getOption } from "../../components/DropdownButton/util";
import { getBuildInData, getNotifyVariablesUser } from "./util";
import { defineExpose } from "vue";
import { useI18n } from 'vue-i18n'

const { t: $t } = useI18n()
const sceneStore = useSceneStore();
const { data: _data } = storeToRefs(sceneStore);

const formItemContext = Form.useInjectFormItemContext();

const props = defineProps({
  branchesName: {
    type: Number,
    default: 0,
  },
  thenName: {
    type: Number,
    default: 0,
  },
  name: {
    type: Number,
    default: 0,
  },
});

const sub = ref();

const formTouchOff = () => {
  formItemContext.onFieldChange();
};

/**
 * 校验当前执行动作的设备或者产品是否删除
 */
const checkDeviceDelete = async () => {
  const item =
    _data.value.branches![props.branchesName].then[props.thenName].actions[
      props.name
    ].device;
  const proResp = await queryProductList({
    terms: [{ column: "id", termType: "eq", value: item!.productId }],
  });

  if (
    proResp.success &&
    (proResp.result as any)?.total === 0 &&
    item &&
    item.productId
  ) {
    // 产品已删除
    _data.value.branches![props.branchesName].then[props.thenName].actions[
      props.name
    ].device!.productId = undefined;
    formTouchOff();
    return;
  }

  const productDetail = proResp?.result?.data?.[0];
  let metadata = JSON.parse(productDetail?.metadata || "{}");
  if (item?.selector === "fixed") {
    let hasDevice = false;
    if (item!.selectorValues) {
      const deviceList = item!.selectorValues?.map((item) => item.value) || [];
      const deviceResp = await queryNoPagingPost({
        terms: [
          {
            terms: [
              { column: "id", termType: "in", value: deviceList.toString() },
            ],
          },
        ],
        paging: false
      });

      hasDevice =
        deviceResp.success &&
        deviceResp.result.length === (item!.selectorValues?.length || 0);

      if (item!.selectorValues!.length === 1 && hasDevice) {
        const deviceDetailResp = await getDeviceDetail(deviceList[0]);
        // const deviceDetail = deviceResp.result?.[0]
        const deviceDetail = deviceDetailResp.result;
        metadata = JSON.parse(
          deviceDetail?.metadata || productDetail?.metadata || "{}"
        ); // 只选中一个设备，以设备物模型为准
      }
    }
    if (!hasDevice) {
      // 某一个设备被删除
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.selectorValues = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  } else if (item!.selector === "context") {
    // 如果是按变量，校验上一个设备输出的产品id
    // if (props.name === 0) {
    //   _data.value.branches![props.branchesName].then[props.thenName].actions[props.name].device!.upperKey = undefined
    //   formTouchOff()
    //   return
    // } else {
    //   const prevItem = _data.value.branches![props.branchesName].then[props.thenName].actions[props.name - 1].device
    //   if (prevItem?.productId !== item?.productId) {
    //     _data.value.branches![props.branchesName].then[props.thenName].actions[props.name].device!.upperKey = undefined
    //     _data.value.branches![props.branchesName].then[props.thenName].actions[props.name].device!.changeData = true
    //     formTouchOff()
    //     return
    //   } else {
    //     const _upperKey = item!.upperKey
    //     const _params = {
    //       branch: props.thenName,
    //       branchGroup: props.branchesName,
    //       action: props.name - 1,
    //     };
    //     const upperData = await getParams(_params, unref(_data.value));
    //     const option = getOption(upperData, _upperKey, 'id')
    //     if (!option) {
    //       _data.value.branches![props.branchesName].then[props.thenName].actions[props.name].device!.upperKey = undefined
    //       _data.value.branches![props.branchesName].then[props.thenName].actions[props.name].device!.changeData = true
    //       formTouchOff()
    //       return
    //     }
    //   }
    // }
    const _upperKey = item!.upperKey;
    const _params = {
      branch: props.branchesName,
      branchGroup: props.thenName,
      action: props.name - 1,
    };
    const upperData = await getParams(_params, unref(_data.value));
    const option = getOption(upperData, _upperKey, "id");
    if (!option) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.upperKey = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  } else if (item!.selector === "relation") {
    const _relationValue = (item!.selectorValues?.[0]?.value as any)?.relation;
    const relationData = await getRelationUsers({
      paging: false,
      sorts: [{ name: "createTime", order: "desc" }],
      terms: [
        { termType: "eq", column: "objectTypeName", value: $t('ListItem.CheckItem.9667712-0') },
        { termType: "eq", column: "relation", value: _relationValue },
      ],
    }).catch(() => ({ success: false, result: [] }));
    if (!relationData.result?.length) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.selectorValues = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  } else if (item!.selector === "tag") {
    let hasAllTags = false;
    if (item!.selectorValues && metadata?.tags?.length) {
      const values = (item!.selectorValues?.[0]?.value as any).map(
        (item: any) => item.column
      );
      const tagKeys = new Set(values);
      hasAllTags = [...tagKeys.values()].every((_key) =>
        metadata?.tags.some((item: any) => item.id === _key)
      );
      // hasAllTags = metadata?.tags?.every((item: any) => tagKeys.has(item.id))
    }
    if (!hasAllTags) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.selectorValues = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  }

  if (item!.message!.messageType === "READ_PROPERTY") {
    let hasProperties = false;
    if (item!.message!.properties && metadata.properties?.length) {
      const propertiesKey = item!.message!.properties?.[0];
      hasProperties = metadata.properties?.some(
        (item: any) => item.id === propertiesKey
      );
    }
    if (!hasProperties) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.message!.properties = [];
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  }
  if (item!.message!.messageType === "WRITE_PROPERTY") {
    let hasProperties = false;
    const propertiesKey = Object.keys(item!.message!.properties!)?.[0];
    if (item!.message!.properties && metadata.properties?.length) {
      hasProperties = metadata.properties?.some(
        (item: any) => item.id === propertiesKey
      );
    }
    if (!hasProperties) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.message!.properties = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
    // 判断值-内置参数
    const _value = item!.message!.properties?.[propertiesKey];

    if (_value.source === "upper") {
      const _params = {
        branch: props.branchesName,
        branchGroup: props.thenName,
        action: props.name - 1,
      };
      const option = (await getBuildInData(_params, _data.value))(
        _value?.value!,
        "id"
      );
      if (!option) {
        _data.value.branches![props.branchesName].then[props.thenName].actions[
          props.name
        ].device!.message!.properties![propertiesKey] = undefined;
        _data.value.branches![props.branchesName].then[props.thenName].actions[
          props.name
        ].device!.changeData = true;
        formTouchOff();
        return;
      }
    }
  }

  if (
    item!.message!.messageType === "INVOKE_FUNCTION" &&
    item!.message!.functionId &&
    metadata.functions
  ) {
    const functionId = item!.message!.functionId;
    let hasFunctions = false;
    if (functionId && metadata.functions.length) {
      hasFunctions = metadata.functions?.some(
        (item: any) => item.id === functionId
      );
    }
    if (!hasFunctions) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.message!.functionId = undefined;
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].device!.changeData = true;
      formTouchOff();
      return;
    }
  }
};

/**
 * 校验当前执行动作的通知配置、消息模板是否删除
 */
const checkNoticeDelete = async () => {
  const item =
    _data.value.branches![props.branchesName].then[props.thenName].actions[
      props.name
    ].notify;
  const _triggerType = _data.value.triggerType;
  const configResp = await queryNoticeList({
    terms: [
      { terms: [{ column: "id", termType: "eq", value: item!.notifierId }] },
    ],
  });
  if (configResp.success && (configResp.result as any)?.total === 0) {
    // 通知配置
    _data.value.branches![props.branchesName].then[props.thenName].actions[
      props.name
    ].notify!.notifierId = "";
    formTouchOff();
    return;
  }
  const templateResp = await queryTemplateList({
    terms: [
      { terms: [{ column: "id", termType: "eq", value: item!.templateId }] },
    ],
  });
  if (templateResp.success && (templateResp.result as any)?.total === 0) {
    // 通知模板
    _data.value.branches![props.branchesName].then[props.thenName].actions[
      props.name
    ].notify!.templateId = "";
    formTouchOff();
    return;
  }
  const templateDetailResp = await getTemplateDetail(
    item!.templateId
  );
  if (templateDetailResp.success) {
    const variableDefinitionsMap = new Map();
    const itemVariableKeys = Object.keys(item!.variables || {});
    const notifyType = item!.notifyType;
    templateDetailResp.result.variableDefinitions.map((dItem: any) => {
      variableDefinitionsMap.set(dItem.id, dItem.expands?.businessType);
    });
    // 判断参数是否发生变化
    let BuildInData: any = null;
    const hasAll = itemVariableKeys.every(async (variableKey: any) => {
      if (variableDefinitionsMap.has(variableKey)) {
        const itemData = item!.variables[variableKey];
        if (itemData.source === "upper") {
          if (!BuildInData) {
            const _params = {
              branch: props.thenName,
              branchGroup: props.branchesName,
              action: props.name - 1,
            };
            BuildInData = await getBuildInData(_params, _data.value);
          }
          const option = BuildInData?.(itemData.upperKey!, "id");
          return !!option;
        } else if (itemData.source === "fixed") {
          const itemType = variableDefinitionsMap.get(variableKey);
          let hasUser = false;

          if (itemType === "user") {
            // 微信用户，钉钉用户
            let resp = undefined;
            if (["dingTalk", "weixin"].includes(notifyType)) {
              resp =
                notifyType === "dingTalk"
                  ? await queryDingTalkUsers(item!.notifierId)
                  : await queryWechatUsers(item!.notifierId);
            } else {
              hasUser = true;
            }

            if (resp && resp.success) {
              hasUser = resp.result.some(
                (uItem: any) => uItem.id === itemData.value
              );
            }
            return hasUser;
          }

          if (itemType === "tag") {
            // 标签
            const resp = await getTags(item!.notifierId);
            if (resp && resp.success) {
              hasUser = resp.result.some(
                (tag: any) => tag.id === itemData.value
              );
            }
            return hasUser;
          }

          if (itemType === "org") {
            // 组织
            let resp = undefined;
            if (["dingTalk", "weixin"].includes(notifyType)) {
              resp =
                notifyType === "dingTalk"
                  ? await dingTalkDept(item!.notifierId)
                  : await weChatDept(item!.notifierId);
            } else {
              hasUser = true;
            }

            if (resp && resp.success) {
              hasUser = resp.result.some(
                (org: any) => org.id === itemData.value
              );
            }
            return hasUser;
          }
        } else if (itemData.source == "relation") {
          // 获取平台用户
          const userData = await getNotifyVariablesUser(
            _triggerType === "device"
          );
          let hasUser = false;
          if (!hasUser && userData.platform.length) {
            // 平台用户
            hasUser = userData.platform.some((uItem) => {
              return (
                uItem.id === (itemData.relation as PlatformRelation)?.objectId
              );
            });
          }
          if (!hasUser && userData.relation.length) {
            // 关系用户
            hasUser = userData.relation.some((uItem) => {
              return (
                uItem.id === (itemData.relation as PlatformRelation)?.objectId
              );
            });
          }
          return hasUser;
        }
      } else {
        return false;
      }
      return true;
    });

    BuildInData = null;

    if (!hasAll) {
      _data.value.branches![props.branchesName].then[props.thenName].actions[
        props.name
      ].notify!.changeData! = true;
      formTouchOff();
      return;
    }
  }
};

const check = () => {
  if (_data.value.branches![props.branchesName].then[props.thenName]) {
    const action =
      _data.value.branches![props.branchesName].then[props.thenName].actions?.[
        props.name
      ];
    const _executor = action?.executor;
    if (_executor === "device" && action?.device) {
      // 设备输出，并且有值
      checkDeviceDelete();
    } else if (_executor === "notify" && action?.notify) {
      checkNoticeDelete();
    }
  }
};

const subscribe = () => {
  // 订阅上一个action
  const _key = EventSubscribeKeys({
    branch: props.branchesName,
    branchGroup: props.thenName,
    action: props.name,
  });

  sub.value = EventEmitter.subscribe(_key, check);
};

subscribe();

check();

defineExpose({
  formTouchOff,
});
</script>

<style scoped></style>
